#include "ply.h"

ply::ply()
{
}


int ply::read(QString filename)
{
    QFile in(filename);
    if(!in.open(QIODevice::ReadOnly))  return 1;
    in.seek(0);         //到原始长度位置
   // olen=in.read(4).toInt();

    in.read((char *)&olen,4);
    in.seek(4);        //到压缩长度位置
   // clen=in.read(4).toInt();
    in.read((char *)&clen,4);

    this->cdata=new char[clen];
    this->odata=new char[olen];

    in.seek(8);
    in.read(cdata,clen);
    lzo::decompress((byte *)cdata,clen,(byte *)odata);
    in.close();

    delete []cdata;

    this->ptop=(modelspace::plytop *)odata;
    pobject=(modelspace::plyobject *)(odata+60);
    pointnum=*(int *)(odata+60+28*ptop->num);
    this->pp=(modelspace::mpoint *)(odata+60+28*ptop->num+4);
    facenum=*(int *)(odata+60+28*ptop->num+4+40*pointnum);
    this->face=(modelspace::face *)(odata+60+28*ptop->num+4+40*pointnum+4);
    wenlinum=*(int *)(odata+60+28*ptop->num+4+40*pointnum+4+facenum*6);
    int offset_wenli=60+28*ptop->num+4+40*pointnum+4+facenum*6+4;
    this->pwenli=(modelspace::wenli *)(odata+offset_wenli);
    objNum=ptop->num;
    int weiliIndexNum=*(int *)(odata+offset_wenli+wenlinum*52);   //纹理索引数
    int offset_weiliIndex=offset_wenli+wenlinum*52+4;    //纹理索引偏移地址
    this->pWeiliIndex=odata+offset_weiliIndex;
    int offset_matrix=offset_weiliIndex+weiliIndexNum*4;
    frameNum=*(int *)(odata+offset_matrix);    //变换矩阵帧数
    offset_matrix+=4;        //变换矩阵偏移位置
    objMatrix=new modelspace::ObjMatrix(objNum,frameNum,(float *)(odata+offset_matrix));     //变换矩阵
    objMatrix->calculateFrame(pp,pointnum,pobject);
    fplyopen=true;
/*

    QFile out(filename+"test.ply");
    out.open(QIODevice::WriteOnly);
    out.write("ply\n");
 //   out.putChar('\n');
    out.write("format ascii 1.0\n");
    out.write("comment author: ?????\n");
    out.write("obj_info random information\n");
    char str[100]=" ";
    sprintf(str,"element vertex %d\n",pointnum);
    out.write(str);
    out.write("property float32 x\n");
    out.write("property float32 y\n");
    out.write("property float32 z\n");
    out.write("property red unit8\n");
    out.write("property green unit8\n");
    out.write("property blue unit8\n");
    sprintf(str,"element face %d\n",facenum);
    out.write(str);
    out.write("property list uint8 int32 vertex_indices\n");
    out.write("end_header\n");
    for(int i=0;i<pointnum;i++)
    {
        sprintf(str,"%.2f %.2f %.2f %d %d %d\n",pp[i].x,pp[i].y,pp[i].z,int(pp[i].none2*255),int(pp[i].none3*255),int(pp[i].none4*255));
        out.write(str);
     //   out.putChar('\n');
    }
    for(int i=0;i<facenum;i++)
    {
        sprintf(str,"3 %d %d %d\n",face[i].index1,face[i].index2,face[i].index3);
        out.write(str);
    }
    out.close();

*/
    return 0;
}

int ply::save(QString filename)
{
    int clen;
   // filename=filename+".comp";
   // if(this->fplyopen==true) return 2;
    char *temp=new char[olen];
    clen=lzo::compress((byte *)odata,olen,(byte *)temp);
    QFile out(filename);
    if(!out.open(QIODevice::ReadWrite)) return 1;
    out.write((char *)&olen,4);
    out.write((char *)&clen,4);
    out.write(temp,clen);
    out.close();
    delete []temp;
    return 0;
}


ply::ply(QString filename)
{
    read(filename);
}

ply::~ply()
{
    delete []odata;
    delete []cdata;
}


void ply::decompress(QString filename)
{
    QFile in(filename);
    int clen,olen;
    char *odata,*cdata;
    if(!in.open(QIODevice::ReadOnly))  return ;
    in.seek(0);         //到原始长度位置
    // olen=in.read(4).toInt();
    in.read((char *)&olen,4);
    in.seek(4);        //到压缩长度位置
    // clen=in.read(4).toInt();
    in.read((char *)&clen,4);
    cdata=new char[clen];
    odata=new char[olen];
    in.seek(8);
    in.read(cdata,clen);
    lzo::decompress((byte *)cdata,clen,(byte *)odata);
    in.close();
    filename=filename+".decomp";
    QFile out(filename);
    if(!out.open(QIODevice::WriteOnly)) return ;
    out.write(odata,olen);
    out.close();
    delete []odata;
    delete []cdata;
}

void ply::compress(QString filename)
{
    char *cdata,*odata;
    int clen,olen;
    QFile in(filename);
    if(!in.open(QIODevice::ReadOnly))  return ;
    olen=in.size();
    odata=new char[olen];
    cdata=new char[olen];
    in.read(odata,olen);
    clen=lzo::compress((byte *)odata,olen,(byte*)(cdata+8));
    *(int *)cdata=olen;
    *(int *)(cdata+4)=clen;
    filename=filename+".comp";
    QFile out(filename);
    if(!out.open(QIODevice::ReadWrite)) return ;
    out.write(cdata,clen+8);
    out.close();
    delete []cdata;
    delete []odata;
}

int ply::getTexIndex(int faceidx)
{
    int i, tmp = 3*faceidx;
    modelspace::wenli *ptex = pwenli;
    for(i=0; i<wenlinum; i++,ptex++){
        if((tmp >= ptex->facestart)&&(tmp < ptex->faceend))
                return i;
    }
    if(i>=wenlinum)
        return -1;
}



